home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-desktop-9.10-i386-PL.iso / casper / filesystem.squashfs / usr / share / hplip / scan / sane.pyc (.txt) < prev   
Python Compiled Bytecode  |  2009-10-28  |  16KB  |  518 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. import scanext
  5. import threading
  6. import time
  7. import os
  8. import Queue
  9. from base.g import *
  10. from base import utils
  11. EVENT_SCAN_CANCELED = 1
  12. TYPE_STR = {
  13.     scanext.TYPE_BOOL: 'TYPE_BOOL',
  14.     scanext.TYPE_INT: 'TYPE_INT',
  15.     scanext.TYPE_FIXED: 'TYPE_FIXED',
  16.     scanext.TYPE_STRING: 'TYPE_STRING',
  17.     scanext.TYPE_BUTTON: 'TYPE_BUTTON',
  18.     scanext.TYPE_GROUP: 'TYPE_GROUP' }
  19. UNIT_STR = {
  20.     scanext.UNIT_NONE: 'UNIT_NONE',
  21.     scanext.UNIT_PIXEL: 'UNIT_PIXEL',
  22.     scanext.UNIT_BIT: 'UNIT_BIT',
  23.     scanext.UNIT_MM: 'UNIT_MM',
  24.     scanext.UNIT_DPI: 'UNIT_DPI',
  25.     scanext.UNIT_PERCENT: 'UNIT_PERCENT',
  26.     scanext.UNIT_MICROSECOND: 'UNIT_MICROSECOND' }
  27.  
  28. class Option:
  29.     '''Class representing a SANE option.
  30.     Attributes:
  31.     index -- number from 0 to n, giving the option number
  32.     name -- a string uniquely identifying the option
  33.     title -- single-line string containing a title for the option
  34.     desc -- a long string describing the option; useful as a help message
  35.     type -- type of this option.  Possible values: TYPE_BOOL,
  36.             TYPE_INT, TYPE_STRING, and so forth.
  37.     unit -- units of this option.  Possible values: UNIT_NONE,
  38.             UNIT_PIXEL, etc.
  39.     size -- size of the value in bytes
  40.     cap -- capabilities available; CAP_EMULATED, CAP_SOFT_SELECT, etc.
  41.     constraint -- constraint on values.  Possible values:
  42.         None : No constraint
  43.         (min,max,step)  Integer values, from min to max, stepping by
  44.         list of integers or strings: only the listed values are allowed
  45.     '''
  46.     
  47.     def __init__(self, args, cur_device):
  48.         import string as string
  49.         self.cur_device = cur_device
  50.         (self.index, self.name, self.title, self.desc, self.type, self.unit, self.size, self.cap, self.constraint) = args
  51.         if type(self.name) != type(''):
  52.             self.name = str(self.name)
  53.         
  54.  
  55.     
  56.     def isActive(self):
  57.         return scanext.isOptionActive(self.cap)
  58.  
  59.     
  60.     def isSettable(self):
  61.         return scanext.isOptionSettable(self.cap)
  62.  
  63.     
  64.     def __repr__(self):
  65.         if self.isSettable():
  66.             settable = 'yes'
  67.         else:
  68.             settable = 'no'
  69.         if self.isActive():
  70.             active = 'yes'
  71.             curValue = self.cur_device.getOption(self.name)
  72.         else:
  73.             active = 'no'
  74.             curValue = '<not available, inactive option>'
  75.         return '\nName:      %s\nCur value: %s\nIndex:     %d\nTitle:     %s\nDesc:      %s\nType:      %s\nUnit:      %s\nConstr:    %s\nisActive:    %s\nisSettable:  %s\n' % (self.name, curValue, self.index, self.title, self.desc, TYPE_STR[self.type], UNIT_STR[self.unit], self.constraint, active, settable)
  76.  
  77.     
  78.     def limitAndSet(self, value):
  79.         if value is not None and self.constraint is not None:
  80.             if type(self.constraint) == type(()):
  81.                 if value < self.constraint[0]:
  82.                     value = self.constraint[0]
  83.                     log.warn('Invalid value for %s (%s < min value of %d). Using %d.' % (self.name, self.name, value, value))
  84.                 elif value > self.constraint[1]:
  85.                     value = self.constraint[1]
  86.                     log.warn('Invalid value for %s (%s > max value of %d). Using %d.' % (self.name, self.name, value, value))
  87.                 
  88.                 self.cur_device.setOption(self.name, value)
  89.             elif type(self.constraint) == type([]):
  90.                 if value not in self.constraint:
  91.                     v = self.constraint[0]
  92.                     min_dist = sys.maxint
  93.                     for x in self.constraint:
  94.                         if abs(value - x) < min_dist:
  95.                             min_dist = abs(value - x)
  96.                             v = x
  97.                             continue
  98.                     
  99.                     log.warn('Invalid value for %s (%s not in constraint list: %s). Using %d.' % (self.name, self.name, value, ', '.join(self.constraint), v))
  100.                     self.cur_device.setOption(self.name, v)
  101.                 
  102.             
  103.         else:
  104.             value = self.cur_device.getOption(self.name)
  105.         return value
  106.  
  107.  
  108.  
  109. class ScanDevice:
  110.     """Class representing a SANE device.
  111.     Methods:
  112.     startScan()    -- initiate a scan, using the current settings
  113.     cancelScan()   -- cancel an in-progress scanning operation
  114.  
  115.     Also available, but rather low-level:
  116.     getParameters() -- get the current parameter settings of the device
  117.     getOptions()    -- return a list of tuples describing all the options.
  118.  
  119.     Attributes:
  120.     optlist -- list of option names
  121.  
  122.     You can also access an option name to retrieve its value, and to
  123.     set it.  For example, if one option has a .name attribute of
  124.     imagemode, and scanner is a ScanDevice object, you can do:
  125.          print scanner.imagemode
  126.          scanner.imagemode = 'Full frame'
  127.          scanner.['imagemode'] returns the corresponding Option object.
  128.     """
  129.     
  130.     def __init__(self, dev):
  131.         self.scan_thread = None
  132.         self.dev = scanext.openDevice(dev)
  133.         self.options = { }
  134.         self._ScanDevice__load_options_dict()
  135.  
  136.     
  137.     def __load_options_dict(self):
  138.         opts = self.options
  139.         opt_list = self.dev.getOptions()
  140.         for t in opt_list:
  141.             o = Option(t, self)
  142.             if o.type != scanext.TYPE_GROUP:
  143.                 opts[o.name] = o
  144.                 continue
  145.         
  146.  
  147.     
  148.     def setOption(self, key, value):
  149.         opts = self.options
  150.         if key not in opts:
  151.             opts[key] = value
  152.             return None
  153.         opt = opts[key]
  154.         if opt.type == scanext.TYPE_GROUP:
  155.             log.error("Groups can't be set: %s" % key)
  156.         
  157.         if not scanext.isOptionActive(opt.cap):
  158.             log.error('Inactive option: %s' % key)
  159.         
  160.         if not scanext.isOptionSettable(opt.cap):
  161.             log.error("Option can't be set by software: %s" % key)
  162.         
  163.         if type(value) == int and opt.type == scanext.TYPE_FIXED:
  164.             value = float(value)
  165.         
  166.         
  167.         try:
  168.             self.last_opt = self.dev.setOption(opt.index, value)
  169.         except scanext.error:
  170.             log.error('Unable to set option %s to value %s' % (key, value))
  171.  
  172.         if self.last_opt & scanext.INFO_RELOAD_OPTIONS:
  173.             self._ScanDevice__load_options_dict()
  174.         
  175.  
  176.     
  177.     def getOption(self, key):
  178.         opts = self.options
  179.         if key == 'optlist':
  180.             return opts.keys()
  181.         if key == 'area':
  182.             return ((opts['tl-x'], opts['tl-y']), (opts['br-x'], opts['br-y']))
  183.         if key not in opts:
  184.             raise AttributeError, 'No such attribute: %s' % key
  185.         key not in opts
  186.         opt = opts[key]
  187.         if opt.type == scanext.TYPE_BUTTON:
  188.             raise AttributeError, "Buttons don't have values: %s" % key
  189.         opt.type == scanext.TYPE_BUTTON
  190.         if opt.type == scanext.TYPE_GROUP:
  191.             raise AttributeError, "Groups don't have values: %s " % key
  192.         opt.type == scanext.TYPE_GROUP
  193.         if not scanext.isOptionActive(opt.cap):
  194.             raise AttributeError, 'Inactive option: %s' % key
  195.         scanext.isOptionActive(opt.cap)
  196.         return self.dev.getOption(opt.index)
  197.  
  198.     
  199.     def getOptionObj(self, key):
  200.         opts = self.options
  201.         if key in opts:
  202.             return opts[key]
  203.  
  204.     
  205.     def getParameters(self):
  206.         """Return a 6-tuple holding all the current device settings:
  207.            (format, format_name, last_frame, (pixels_per_line, lines), depth, bytes_per_line)
  208.  
  209.             - format is the SANE frame type
  210.             - format is one of 'grey', 'color' (RGB), 'red', 'green', 'blue'.
  211.             - last_frame [bool] indicates if this is the last frame of a multi frame image
  212.             - (pixels_per_line, lines) specifies the size of the scanned image (x,y)
  213.             - lines denotes the number of scanlines per frame
  214.             - depth gives number of pixels per sample
  215.         """
  216.         return self.dev.getParameters()
  217.  
  218.     
  219.     def getOptions(self):
  220.         '''Return a list of tuples describing all the available options'''
  221.         return self.dev.getOptions()
  222.  
  223.     
  224.     def startScan(self, byte_format = 'BGRA', update_queue = None, event_queue = None):
  225.         '''
  226.             Perform a scan with the current device.
  227.             Calls sane_start().
  228.         '''
  229.         if not self.isScanActive():
  230.             status = self.dev.startScan()
  231.             (self.format, self.format_name, self.last_frame, self.pixels_per_line, self.lines, self.depth, self.bytes_per_line) = self.dev.getParameters()
  232.             self.scan_thread = ScanThread(self.dev, byte_format, update_queue, event_queue)
  233.             self.scan_thread.scan_active = True
  234.             self.scan_thread.start()
  235.             return (True, self.lines * self.bytes_per_line, status)
  236.         return (False, 0, scanext.SANE_STATUS_DEVICE_BUSY)
  237.  
  238.     
  239.     def cancelScan(self):
  240.         '''Cancel an in-progress scanning operation.'''
  241.         return self.dev.cancelScan()
  242.  
  243.     
  244.     def getScan(self):
  245.         '''Get the output buffer and info about a completed scan.'''
  246.         if not self.isScanActive():
  247.             s = self.scan_thread
  248.             return (s.buffer, s.format, s.format_name, s.pixels_per_line, s.lines, s.depth, s.bytes_per_line, s.pad_bytes, s.total_read)
  249.  
  250.     
  251.     def freeScan(self):
  252.         '''Cleanup the scan file after a completed scan.'''
  253.         if not self.isScanActive():
  254.             s = self.scan_thread
  255.             
  256.             try:
  257.                 s.buffer.close()
  258.                 os.remove(s.buffer_path)
  259.             except (IOError, AttributeError):
  260.                 pass
  261.             except:
  262.                 None<EXCEPTION MATCH>(IOError, AttributeError)
  263.             
  264.  
  265.         None<EXCEPTION MATCH>(IOError, AttributeError)
  266.  
  267.     
  268.     def isScanActive(self):
  269.         if self.scan_thread is not None:
  270.             if self.scan_thread.isAlive():
  271.                 pass
  272.             return self.scan_thread.scan_active
  273.         return False
  274.  
  275.     
  276.     def waitForScanDone(self):
  277.         if self.scan_thread is not None and self.scan_thread.isAlive() and self.scan_thread.scan_active:
  278.             
  279.             try:
  280.                 self.scan_thread.join()
  281.             except KeyboardInterrupt:
  282.                 pass
  283.             except:
  284.                 None<EXCEPTION MATCH>KeyboardInterrupt
  285.             
  286.  
  287.         None<EXCEPTION MATCH>KeyboardInterrupt
  288.  
  289.     
  290.     def waitForScanActive(self):
  291.         time.sleep(0.5)
  292.         if self.scan_thread is not None:
  293.             while True:
  294.                 if self.scan_thread.isAlive() and self.scan_thread.scan_active:
  295.                     return None
  296.                 time.sleep(0.5)
  297.                 continue
  298.                 self.scan_thread.scan_active
  299.         
  300.  
  301.     
  302.     def closeScan(self):
  303.         '''Close the SANE device after a scan.'''
  304.         self.dev.closeScan()
  305.  
  306.  
  307.  
  308. class ScanThread(threading.Thread):
  309.     
  310.     def __init__(self, device, byte_format = 'BGRA', update_queue = None, event_queue = None):
  311.         threading.Thread.__init__(self)
  312.         self.scan_active = True
  313.         self.dev = device
  314.         self.update_queue = update_queue
  315.         self.event_queue = event_queue
  316.         (self.buffer_fd, self.buffer_path) = utils.make_temp_file(prefix = 'hpscan')
  317.         self.buffer = os.fdopen(self.buffer_fd, 'w+b')
  318.         self.format = -1
  319.         self.format_name = ''
  320.         self.last_frame = -1
  321.         self.pixels_per_line = -1
  322.         self.lines = -1
  323.         self.depth = -1
  324.         self.bytes_per_line = -1
  325.         self.pad_bytes = -1
  326.         self.total_read = 0
  327.         self.byte_format = byte_format
  328.  
  329.     
  330.     def updateQueue(self, status, bytes_read):
  331.         if self.update_queue is not None:
  332.             
  333.             try:
  334.                 status = int(status)
  335.             except (ValueError, TypeError):
  336.                 status = -1
  337.  
  338.             self.update_queue.put((status, bytes_read))
  339.             time.sleep(0)
  340.         
  341.  
  342.     
  343.     def run(self):
  344.         (self.format, self.format_name, self.last_frame, self.pixels_per_line, self.lines, self.depth, self.bytes_per_line) = self.dev.getParameters()
  345.         log.debug('format=%d' % self.format)
  346.         log.debug('format_name=%s' % self.format_name)
  347.         log.debug('last_frame=%d' % self.last_frame)
  348.         log.debug('ppl=%d' % self.pixels_per_line)
  349.         log.debug('lines=%d' % self.lines)
  350.         log.debug('depth=%d' % self.depth)
  351.         log.debug('bpl=%d' % self.bytes_per_line)
  352.         log.debug('byte_format=%s' % self.byte_format)
  353.         w = self.buffer.write
  354.         if self.format == scanext.FRAME_RGB:
  355.             if self.depth == 8:
  356.                 self.pad_bytes = self.bytes_per_line - 3 * self.pixels_per_line
  357.                 log.debug('pad_bytes=%d' % self.pad_bytes)
  358.                 dir = -1
  359.                 if self.byte_format == 'RGBA':
  360.                     dir = 1
  361.                 
  362.                 
  363.                 try:
  364.                     (st, t) = self.dev.readScan(self.bytes_per_line)
  365.                 except scanext.error:
  366.                     st = None
  367.                     self.updateQueue(st, 0)
  368.  
  369.                 while st == scanext.SANE_STATUS_GOOD:
  370.                     if t:
  371.                         index = 0
  372.                         while index < len(t) - self.pad_bytes:
  373.                             w(t[index:index + 3:dir])
  374.                             w('\xff')
  375.                             index += 3
  376.                         self.total_read += len(t)
  377.                         self.updateQueue(st, self.total_read)
  378.                         log.debug('Read %d bytes' % self.total_read)
  379.                     else:
  380.                         time.sleep(0.1)
  381.                     
  382.                     try:
  383.                         (st, t) = self.dev.readScan(self.bytes_per_line)
  384.                     except scanext.error:
  385.                         st = None
  386.                         self.updateQueue(st, self.total_read)
  387.                         break
  388.  
  389.                     if self.checkCancel():
  390.                         break
  391.                         continue
  392.             
  393.         elif self.format == scanext.FRAME_GRAY:
  394.             if self.depth == 1:
  395.                 self.pad_bytes = self.bytes_per_line - (self.pixels_per_line + 7) // 8
  396.                 log.debug('pad_bytes=%d' % self.pad_bytes)
  397.                 
  398.                 try:
  399.                     (st, t) = self.dev.readScan(self.bytes_per_line)
  400.                 except scanext.error:
  401.                     st = None
  402.                     self.updateQueue(st, 0)
  403.  
  404.                 while st == scanext.SANE_STATUS_GOOD:
  405.                     if t:
  406.                         index = 0
  407.                         while index < len(t) - self.pad_bytes:
  408.                             k = 128
  409.                             j = ord(t[index])
  410.                             for b in range(8):
  411.                                 if k & j:
  412.                                     w('\x00\x00\x00\xff')
  413.                                 else:
  414.                                     w('\xff\xff\xff\xff')
  415.                                 k = k >> 1
  416.                             
  417.                             index += 1
  418.                         self.total_read += len(t)
  419.                         self.updateQueue(st, self.total_read)
  420.                         log.debug('Read %d bytes' % self.total_read)
  421.                     else:
  422.                         time.sleep(0.1)
  423.                     
  424.                     try:
  425.                         (st, t) = self.dev.readScan(self.bytes_per_line)
  426.                     except scanext.error:
  427.                         st = None
  428.                         self.updateQueue(st, self.total_read)
  429.                         break
  430.  
  431.                     if self.checkCancel():
  432.                         break
  433.                         continue
  434.             elif self.depth == 8:
  435.                 self.pad_bytes = self.bytes_per_line - self.pixels_per_line
  436.                 log.debug('pad_bytes=%d' % self.pad_bytes)
  437.                 
  438.                 try:
  439.                     (st, t) = self.dev.readScan(self.bytes_per_line)
  440.                 except scanext.error:
  441.                     st = None
  442.                     self.updateQueue(st, 0)
  443.  
  444.                 while st == scanext.SANE_STATUS_GOOD:
  445.                     if t:
  446.                         index = 0
  447.                         while index < len(t) - self.pad_bytes:
  448.                             j = t[index]
  449.                             w(j)
  450.                             w(j)
  451.                             w(j)
  452.                             w('\xff')
  453.                             index += 1
  454.                         self.total_read += len(t)
  455.                         self.updateQueue(st, self.total_read)
  456.                         log.debug('Read %d bytes' % self.total_read)
  457.                     else:
  458.                         time.sleep(0.1)
  459.                     
  460.                     try:
  461.                         (st, t) = self.dev.readScan(self.bytes_per_line)
  462.                     except scanext.error:
  463.                         st = None
  464.                         self.updateQueue(st, self.total_read)
  465.                         break
  466.  
  467.                     if self.checkCancel():
  468.                         break
  469.                         continue
  470.             
  471.         
  472.         self.buffer.seek(0)
  473.         self.scan_active = False
  474.         log.debug('Scan thread exiting...')
  475.  
  476.     
  477.     def checkCancel(self):
  478.         canceled = False
  479.         while self.event_queue.qsize():
  480.             
  481.             try:
  482.                 event = self.event_queue.get(0)
  483.                 if event == EVENT_SCAN_CANCELED:
  484.                     canceled = True
  485.                     log.debug('Cancel pressed!')
  486.                     self.dev.cancelScan()
  487.             continue
  488.             except Queue.Empty:
  489.                 break
  490.                 continue
  491.             
  492.  
  493.             None<EXCEPTION MATCH>Queue.Empty
  494.         return canceled
  495.  
  496.  
  497.  
  498. def init():
  499.     return scanext.init()
  500.  
  501.  
  502. def deInit():
  503.     return scanext.deInit()
  504.  
  505.  
  506. def openDevice(dev):
  507.     '''Open a device for scanning'''
  508.     return ScanDevice(dev)
  509.  
  510.  
  511. def getDevices(local_only = 0):
  512.     return scanext.getDevices(local_only)
  513.  
  514.  
  515. def reportError(code):
  516.     log.error('SANE: %s (code=%d)' % (scanext.getErrorMessage(code), code))
  517.  
  518.